﻿#region header

//  ***************************************************************************
// *                                LICENSE
//  ***************************************************************************
//  * "Haplous" .NET Simple 2D Game Framework
//  * 
//  * Copyright © Jonathan Evans 2014-2014
//  * 
//  * This program is free software; you can redistribute it and/or
//  * modify it under the terms of the GNU General Public License
//  * as published by the Free Software Foundation; either version 2
//  * of the License, or (at your option) any later version.
//  * 
//  * This program is distributed in the hope that it will be useful,
//  * but WITHOUT ANY WARRANTY; without even the implied warranty of
//  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  * GNU General Public License for more details.
//  * 
//  * You should have received a copy of the GNU General Public License
//  * along with this program; if not, write to the Free Software
//  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//  * 
//  ***************************************************************************
//  * 
//  * Contact: opencollar@googlemail.com
//  * 
//  * Website: http://haplous.codeplex.com/
//  *
//  * NuGet:   http://www.nuget.org/packages/haplous/
//  *
//  * File:    Haplous/Haplous/GameArea.xaml.cs
//  *
//  ***************************************************************************

#endregion

using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Controls;

using Haplous.Core;
using Haplous.Presentation.ViewModel;

using JetBrains.Annotations;

namespace Haplous.Presentation
{
    /// <summary>
    ///     A user control in which the action of a game will be displayed.
    /// </summary>
    public sealed partial class GameArea : UserControl
    {
        /// <summary>
        ///     The view model.
        /// </summary>
        [NotNull]
        private readonly GameAreaViewModel _viewModel;

        #region Game Property

        /// <summary>
        ///     A property that allows the object that will control the game specified.
        /// </summary>
        [NotNull]
        public static readonly DependencyProperty GameProperty = DependencyProperty.Register("Game", typeof(Game), typeof(GameArea), new PropertyMetadata(null, GamePropertyChanged));

        /// <summary>
        ///     Gets or sets the game controller object that defines the game to be displayed.
        /// </summary>
        /// <value>The game controller object.</value>
        [CanBeNull]
        public Game Game
        {
            get { return (Game)GetValue(GameProperty); }
            set { SetValue(GameProperty, value); }
        }

        /// <summary>
        ///     Called whenever the game property changes.
        /// </summary>
        /// <param name="d">The dependency object on which the property has changed.</param>
        /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs" /> instance containing the event data.</param>
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private static void GamePropertyChanged([NotNull] DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                var c = d as GameArea;
                if(c == null)
                    return;

                // Handle the game property changing.
                c._viewModel.Game = (Game)e.NewValue;
            }
            catch(Exception ex)
            {
                ErrorManager.OnUnhandledException(ex);
            }
        }

        #endregion

        /// <summary>
        ///     Initializes a new instance of the <see cref="GameArea" /> class.
        /// </summary>
        public GameArea()
        {
            InitializeComponent();

            // This has the effect of instantiating the view model - so don't remove.
            _viewModel = (GameAreaViewModel)FindResource("ViewModel");
        }

        /// <summary>
        ///     Called when the size of the game container changes.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="SizeChangedEventArgs" /> instance containing the event data.</param>
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void GameContainerSizeChanged([NotNull] object sender, [NotNull] SizeChangedEventArgs e)
        {
            try
            {
                _viewModel.ActualSize.Width = GameContainer.ActualWidth;
                _viewModel.ActualSize.Height = GameContainer.ActualHeight;
            }
            catch(Exception ex)
            {
                ErrorManager.OnUnhandledException(ex);
            }
        }

        /// <summary>
        ///     Handles the Unloaded event of the GameArea control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
        [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        private void GameArea_OnUnloaded([CanBeNull] object sender, [NotNull] RoutedEventArgs e)
        {
            try
            {
                _viewModel.Unloaded();
            }
            catch(Exception ex)
            {
                ErrorManager.OnUnhandledException(ex);
            }
        }
    }
}